package analyzer

import (
	"ddl_checker/pkg/types"
	"fmt"
	"strings"

	"github.com/pingcap/tidb/pkg/parser"
	"github.com/pingcap/tidb/pkg/parser/ast"
	"github.com/pingcap/tidb/pkg/parser/model"
	_ "github.com/pingcap/tidb/pkg/parser/test_driver" // 添加测试驱动
)

// TiDBAnalyzer TiDB SQL分析器实现
type TiDBAnalyzer struct {
	parser      *parser.Parser
	enableDebug bool
}

// NewTiDBAnalyzer 创建新的TiDB分析器
func NewTiDBAnalyzer(enableDebug bool) *TiDBAnalyzer {
	p := parser.New()
	return &TiDBAnalyzer{
		parser:      p,
		enableDebug: enableDebug,
	}
}

// ParseBatch 解析多条SQL语句，拆分成多条
func (ta *TiDBAnalyzer) ParseBatch(sql string, separator string) ([]*SQLStatement, error) {
	// 如果没有提供分隔符，使用默认的分号
	if separator == "" {
		separator = ";"
	}

	// 使用TiDB解析器解析SQL
	stmtNodes, _, err := ta.parser.Parse(sql, "", "")
	if err != nil {
		return nil, fmt.Errorf("failed to parse SQL: %w", err)
	}

	statements := make([]*SQLStatement, len(stmtNodes))
	for i, stmtNode := range stmtNodes {
		statements[i] = ta.parseStatementNode(stmtNode, sql)
	}

	return statements, nil
}

// ParseSingle 解析单条SQL语句
func (ta *TiDBAnalyzer) ParseSingle(sql string) (*SQLStatement, error) {
	stmtNodes, _, err := ta.parser.Parse(sql, "", "")
	if err != nil {
		return nil, fmt.Errorf("failed to parse SQL: %w", err)
	}

	if len(stmtNodes) == 0 {
		return nil, fmt.Errorf("no statements found")
	}

	return ta.parseStatementNode(stmtNodes[0], sql), nil
}

// ValidateSQL 验证SQL语句的语法正确性
func (ta *TiDBAnalyzer) ValidateSQL(sql string) (bool, string) {
	_, _, err := ta.parser.Parse(sql, "", "")
	if err != nil {
		return false, err.Error()
	}
	return true, "SQL syntax is valid"
}

// SplitStatements 分割SQL语句，不进行语法解析
func (ta *TiDBAnalyzer) SplitStatements(sql string, separator string) ([]string, error) {
	// 如果没有提供分隔符，使用默认的分号
	if separator == "" {
		separator = ";"
	}

	// 使用TiDB解析器来分割语句
	stmtNodes, _, err := ta.parser.Parse(sql, "", "")
	if err != nil {
		return nil, fmt.Errorf("failed to parse SQL: %w", err)
	}

	// 提取每个语句的原始文本
	statements := make([]string, len(stmtNodes))
	for i, stmtNode := range stmtNodes {
		statements[i] = ta.extractOriginalSQL(stmtNode, sql)
	}

	return statements, nil
}

// parseStatementNode 解析单个语句节点
func (ta *TiDBAnalyzer) parseStatementNode(stmtNode ast.StmtNode, originalSQL string) *SQLStatement {
	stmt := NewSQLStatement(ta.extractOriginalSQL(stmtNode, originalSQL))
	stmt.IsValid = true
	stmt.ParserUsed = types.ParserUsedTiDB

	switch node := stmtNode.(type) {
	case *ast.CreateTableStmt:
		ta.parseCreateTable(stmt, node)
	case *ast.DropTableStmt:
		ta.parseDropTable(stmt, node)
	case *ast.AlterTableStmt:
		ta.parseAlterTable(stmt, node)
	case *ast.InsertStmt:
		ta.parseInsert(stmt, node)
	case *ast.UpdateStmt:
		ta.parseUpdate(stmt, node)
	case *ast.DeleteStmt:
		ta.parseDelete(stmt, node)
	case *ast.SelectStmt:
		ta.parseSelect(stmt, node)
	case *ast.CreateIndexStmt:
		ta.parseCreateIndex(stmt, node)
	default:
		stmt.StatementType = types.StatementTypeUnknown
	}

	if ta.enableDebug {
		fmt.Printf("TiDB Parsed SQL: %s\n", stmt.OriginalSQL)
		fmt.Printf("Statement Type: %s\n", stmt.StatementType)
		fmt.Printf("Tables: %v\n", stmt.Tables)
		fmt.Printf("Columns: %v\n", stmt.Columns)
		fmt.Printf("Operations: %v\n", stmt.Operations)
	}

	return stmt
}

// parseCreateTable 解析CREATE TABLE语句
func (ta *TiDBAnalyzer) parseCreateTable(stmt *SQLStatement, node *ast.CreateTableStmt) {
	stmt.StatementType = types.StatementTypeCreateTable
	stmt.Operations = append(stmt.Operations, "CREATE_TABLE")

	// 提取表名
	if node.Table != nil {
		tableName := ta.formatTableName(node.Table.Schema, node.Table.Name)
		stmt.Tables = append(stmt.Tables, tableName)
		stmt.TableName = tableName
		stmt.Schema = node.Table.Schema.O
	}

	// 提取列信息
	for _, col := range node.Cols {
		columns := ta.extractColumnFromDef(col)
		stmt.Columns = append(stmt.Columns, columns...)
	}
}

// parseDropTable 解析DROP TABLE语句
func (ta *TiDBAnalyzer) parseDropTable(stmt *SQLStatement, node *ast.DropTableStmt) {
	stmt.StatementType = types.StatementTypeDropTable
	stmt.Operations = append(stmt.Operations, "DROP_TABLE")

	// 提取表名
	for _, table := range node.Tables {
		tableName := ta.formatTableName(table.Schema, table.Name)
		stmt.Tables = append(stmt.Tables, tableName)
	}
}

// parseAlterTable 解析ALTER TABLE语句
func (ta *TiDBAnalyzer) parseAlterTable(stmt *SQLStatement, node *ast.AlterTableStmt) {
	stmt.StatementType = types.StatementTypeAlterTable
	stmt.Operations = append(stmt.Operations, "ALTER_TABLE")

	// 提取表名
	if node.Table != nil {
		tableName := ta.formatTableName(node.Table.Schema, node.Table.Name)
		stmt.Tables = append(stmt.Tables, tableName)
		stmt.TableName = tableName
		stmt.Schema = node.Table.Schema.O
	}

	// 解析操作类型
	for _, spec := range node.Specs {
		switch spec.Tp {
		case ast.AlterTableAddColumns:
			stmt.Operations = append(stmt.Operations, "ADD_COLUMN")
			if spec.NewColumns != nil {
				for _, col := range spec.NewColumns {
					columns := ta.extractColumnFromDef(col)
					stmt.Columns = append(stmt.Columns, columns...)
				}
			}
		case ast.AlterTableDropColumn:
			stmt.Operations = append(stmt.Operations, "DROP_COLUMN")
			if spec.OldColumnName != nil {
				stmt.Columns = append(stmt.Columns, spec.OldColumnName.String())
			}
		case ast.AlterTableModifyColumn:
			stmt.Operations = append(stmt.Operations, "MODIFY_COLUMN")
			if spec.NewColumns != nil {
				for _, col := range spec.NewColumns {
					columns := ta.extractColumnFromDef(col)
					stmt.Columns = append(stmt.Columns, columns...)
				}
			}
		}
	}
}

// parseInsert 解析INSERT语句
func (ta *TiDBAnalyzer) parseInsert(stmt *SQLStatement, node *ast.InsertStmt) {
	stmt.StatementType = types.StatementTypeInsert
	stmt.Operations = append(stmt.Operations, "INSERT")

	// 提取表名
	if node.Table != nil {
		tables := ta.extractTablesFromTableRefs(node.Table)
		stmt.Tables = append(stmt.Tables, tables...)
		if len(tables) > 0 {
			// 对于单表INSERT，设置主表名
			stmt.TableName = tables[0]
			// 尝试从表名中提取schema
			if parts := strings.Split(tables[0], "."); len(parts) > 1 {
				stmt.Schema = parts[0]
			}
		}
	}

	// 提取列名
	if node.Columns != nil {
		for _, col := range node.Columns {
			stmt.Columns = append(stmt.Columns, col.String())
		}
	}
}

// parseUpdate 解析UPDATE语句
func (ta *TiDBAnalyzer) parseUpdate(stmt *SQLStatement, node *ast.UpdateStmt) {
	stmt.StatementType = types.StatementTypeUpdate
	stmt.Operations = append(stmt.Operations, "UPDATE")

	// 提取表名
	if node.TableRefs != nil {
		tables := ta.extractTablesFromTableRefs(node.TableRefs)
		stmt.Tables = append(stmt.Tables, tables...)
		if len(tables) > 0 {
			// 对于单表UPDATE，设置主表名
			stmt.TableName = tables[0]
			// 尝试从表名中提取schema
			if parts := strings.Split(tables[0], "."); len(parts) > 1 {
				stmt.Schema = parts[0]
			}
		}
	}

	// 提取更新的列
	if node.List != nil {
		for _, assignment := range node.List {
			if assignment.Column != nil {
				stmt.Columns = append(stmt.Columns, assignment.Column.String())
			}
		}
	}
}

// parseDelete 解析DELETE语句
func (ta *TiDBAnalyzer) parseDelete(stmt *SQLStatement, node *ast.DeleteStmt) {
	stmt.StatementType = types.StatementTypeDelete
	stmt.Operations = append(stmt.Operations, "DELETE")

	// 提取表名
	if node.TableRefs != nil {
		tables := ta.extractTablesFromTableRefs(node.TableRefs)
		stmt.Tables = append(stmt.Tables, tables...)
		if len(tables) > 0 {
			// 对于单表DELETE，设置主表名
			stmt.TableName = tables[0]
			// 尝试从表名中提取schema
			if parts := strings.Split(tables[0], "."); len(parts) > 1 {
				stmt.Schema = parts[0]
			}
		}
	}
}

// parseSelect 解析SELECT语句
func (ta *TiDBAnalyzer) parseSelect(stmt *SQLStatement, node *ast.SelectStmt) {
	stmt.StatementType = types.StatementTypeSelect
	stmt.Operations = append(stmt.Operations, "SELECT")

	// 提取表名
	if node.From != nil {
		tables := ta.extractTablesFromTableRefs(node.From)
		stmt.Tables = append(stmt.Tables, tables...)
	}

	// 提取列名
	if node.Fields != nil {
		for _, field := range node.Fields.Fields {
			if field.WildCard != nil {
				// SELECT * 的情况，暂时不提取具体列名
				continue
			}
			if field.Expr != nil {
				columns := ta.extractColumnsFromExpr(field.Expr)
				stmt.Columns = append(stmt.Columns, columns...)
			}
		}
	}
}

// parseCreateIndex 解析CREATE INDEX语句
func (ta *TiDBAnalyzer) parseCreateIndex(stmt *SQLStatement, node *ast.CreateIndexStmt) {
	stmt.StatementType = types.StatementTypeCreateIndex
	stmt.Operations = append(stmt.Operations, "CREATE_INDEX")

	// 提取表名
	if node.Table != nil {
		tableName := ta.formatTableName(node.Table.Schema, node.Table.Name)
		stmt.Tables = append(stmt.Tables, tableName)
		stmt.TableName = tableName
		stmt.Schema = node.Table.Schema.O
	}
}

// extractTablesFromTableRefs 从表引用中提取表名
func (ta *TiDBAnalyzer) extractTablesFromTableRefs(tableRefs *ast.TableRefsClause) []string {
	var tables []string
	if tableRefs == nil || tableRefs.TableRefs == nil {
		return tables
	}

	return ta.extractTablesFromJoin(tableRefs.TableRefs)
}

// extractTablesFromJoin 从JOIN中提取表名
func (ta *TiDBAnalyzer) extractTablesFromJoin(join *ast.Join) []string {
	var tables []string

	// 处理左表
	if join.Left != nil {
		switch left := join.Left.(type) {
		case *ast.TableSource:
			if tableName, ok := left.Source.(*ast.TableName); ok {
				tables = append(tables, ta.formatTableName(tableName.Schema, tableName.Name))
			}
		case *ast.Join:
			// 递归处理嵌套的JOIN
			leftTables := ta.extractTablesFromJoin(left)
			tables = append(tables, leftTables...)
		}
	}

	// 处理右表
	if join.Right != nil {
		switch right := join.Right.(type) {
		case *ast.TableSource:
			if tableName, ok := right.Source.(*ast.TableName); ok {
				tables = append(tables, ta.formatTableName(tableName.Schema, tableName.Name))
			}
		case *ast.Join:
			// 递归处理嵌套的JOIN
			rightTables := ta.extractTablesFromJoin(right)
			tables = append(tables, rightTables...)
		}
	}

	return tables
}

// extractColumnsFromExpr 从表达式提取列名
func (ta *TiDBAnalyzer) extractColumnsFromExpr(expr ast.ExprNode) []string {
	var columns []string

	switch node := expr.(type) {
	case *ast.ColumnNameExpr:
		if node.Name != nil {
			columns = append(columns, node.Name.String())
		}
	case ast.ValueExpr:
		// 常量值，不包含列名
	case *ast.BinaryOperationExpr:
		// 二元操作，递归处理左右操作数
		left := ta.extractColumnsFromExpr(node.L)
		right := ta.extractColumnsFromExpr(node.R)
		columns = append(columns, left...)
		columns = append(columns, right...)
	}

	return columns
}

// extractColumnFromDef 从列定义提取列名
func (ta *TiDBAnalyzer) extractColumnFromDef(col *ast.ColumnDef) []string {
	var columns []string
	if col.Name != nil {
		columns = append(columns, col.Name.String())
	}
	return columns
}

// formatTableName 格式化表名
func (ta *TiDBAnalyzer) formatTableName(schema model.CIStr, name model.CIStr) string {
	if schema.O != "" {
		return schema.O + "." + name.O
	}
	return name.O
}

// extractOriginalSQL 从原始SQL中提取语句文本
func (ta *TiDBAnalyzer) extractOriginalSQL(stmtNode ast.StmtNode, originalSQL string) string {
	// TiDB解析器不提供精确的位置信息，我们使用简单的文本分割
	// 这是一个简化的实现，实际应用中可能需要更复杂的逻辑
	text := stmtNode.Text()
	if text == "" {
		// 如果无法获取文本，尝试从原始SQL中提取
		stmtType := ta.getStatementType(stmtNode)
		return ta.extractStatementByType(originalSQL, stmtType)
	}
	return text
}

// getStatementType 获取语句类型
func (ta *TiDBAnalyzer) getStatementType(stmtNode ast.StmtNode) string {
	switch stmtNode.(type) {
	case *ast.CreateTableStmt:
		return "CREATE TABLE"
	case *ast.DropTableStmt:
		return "DROP TABLE"
	case *ast.AlterTableStmt:
		return "ALTER TABLE"
	case *ast.InsertStmt:
		return "INSERT"
	case *ast.UpdateStmt:
		return "UPDATE"
	case *ast.DeleteStmt:
		return "DELETE"
	case *ast.SelectStmt:
		return "SELECT"
	case *ast.CreateIndexStmt:
		return "CREATE INDEX"
	default:
		return ""
	}
}

// extractStatementByType 根据语句类型从原始SQL中提取语句
func (ta *TiDBAnalyzer) extractStatementByType(originalSQL, stmtType string) string {
	// 这是一个简化的实现，实际应用中需要更复杂的逻辑
	lines := strings.Split(originalSQL, "\n")
	for _, line := range lines {
		if strings.Contains(strings.ToUpper(line), stmtType) {
			return strings.TrimSpace(line)
		}
	}
	return originalSQL
}
